package com.jsyxdl.listener;

import cn.hutool.extra.spring.SpringUtil;
import com.hustcad.plm.pdm.classification.service.TyplmClassificationService;
import com.hustcad.plm.pdm.doc.vo.DocDetails;
import com.hustcad.plm.pdm.file.service.FileDownCenterService;
import com.hustcad.plm.pdm.file.service.QueryDownloadDocService;
import com.hustcad.plm.pdm.file.service.TyplmFileHandleService;
import com.hustcad.plm.pdm.file.service.TyplmFileService;
import com.hustcad.plm.pdm.filevault.model.vo.FileDataVO;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowObject;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowObjectPackageLink;
import com.hustcad.plm.pdm.flowbusiness.service.TyplmFlowObjectPackageLinkService;
import com.hustcad.plm.pdm.middle.partbom.service.TyplmPdmPartService;
import com.hustcad.plm.pdm.partbom.service.TyplmPartService;
import com.hustcad.plm.pdm.partbom.vo.PartDetailsVO;
import com.hustcad.plm.pdm.type.service.TyplmTypeService;
import com.hustcad.plm.pdm.workflow.annotion.CustomListener;
import com.hustcad.plm.pdm.workflow.model.entity.WorkFlowContainer;
import com.hustcad.plm.pdm.workflow.service.TyplmWorkFlowContainerService;
import com.jsyxdl.entity.CisAdDTO;
import com.jsyxdl.service.CisAdDTOService;
import com.ty.basic.entity.IdentifierEntity;
import com.ty.basic.service.snow.SnowflakeIdComponent;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@CustomListener(
        category = "其他"
        , description = "提交时检查里面的电子物料的相关资料是否符合要求"
)
public class CheckCISIntergrateListener implements ExecutionListener, TaskListener {
    private static final Logger log = LoggerFactory.getLogger(CheckCISIntergrateListener.class);

    @Override
    public void notify(DelegateExecution delegateExecution) {
        try {
            String workFlowContainerId = delegateExecution.getProcessInstanceBusinessKey();
            if (StringUtils.isBlank(workFlowContainerId)) {
                workFlowContainerId = delegateExecution.getVariable("workFlowContainerId").toString();
            }

            List<PartDetailsVO> partDetailsVOList = this.getPartDetailsVOList(workFlowContainerId);
            this.checkWorkflowPart(partDetailsVOList);
        } catch (Exception e) {
            log.error("监听CheckCISIntergrateListener异常：", e);
            throw e;
        }
    }

    @Override
    public void notify(DelegateTask delegateTask) {
        try {
            String workFlowContainerId = delegateTask.getVariable("workFlowContainerId").toString();
            if (StringUtils.isBlank(workFlowContainerId)) {
                workFlowContainerId = delegateTask.getVariable("workFlowContainerId").toString();
            }

            List<PartDetailsVO> partDetailsVOList = this.getPartDetailsVOList(workFlowContainerId);
            this.checkWorkflowPart(partDetailsVOList);
        } catch (Exception e) {
            log.error("监听CheckCISIntergrateListener异常：", e);
            throw e;
        }
    }

    /***
     * 从流程获取本次进行物料选型流程的零部件的详情信息
     * @param workFlowContainerId
     * @return
     */
    public List<PartDetailsVO> getPartDetailsVOList(String workFlowContainerId) {
        List<PartDetailsVO> result = new ArrayList<>();

        TyplmWorkFlowContainerService typlmWorkFlowContainerService = (TyplmWorkFlowContainerService) SpringUtil.getBean(
                TyplmWorkFlowContainerService.class);
        TyplmPartService typlmPartService = (TyplmPartService) SpringUtil.getBean(
                TyplmPartService.class);
        FileDownCenterService fileDownCenterService = (FileDownCenterService) SpringUtil.getBean(
                FileDownCenterService.class);
        QueryDownloadDocService queryDownloadDocService = (QueryDownloadDocService) SpringUtil.getBean(
                QueryDownloadDocService.class);
        SnowflakeIdComponent snowflakeIdComponent = (SnowflakeIdComponent) SpringUtil.getBean(
                SnowflakeIdComponent.class);
        TyplmTypeService typlmTypeService = (TyplmTypeService) SpringUtil.getBean(
                TyplmTypeService.class);

        WorkFlowContainer workFlowContainer = (WorkFlowContainer) typlmWorkFlowContainerService.selectOneByOid(
                new BigInteger(workFlowContainerId));
        String baseObjectOtype = workFlowContainer.getBaseObjectOtype();
        if ("com.ty.entity.workFlow.FlowObjectPackage".equals(baseObjectOtype)) {
            TyplmFlowObjectPackageLinkService typlmFlowObjectPackageLinkService = (TyplmFlowObjectPackageLinkService) SpringUtil.getBean(
                    TyplmFlowObjectPackageLinkService.class);
            List<FlowObjectPackageLink> listByPackage = typlmFlowObjectPackageLinkService.getListByPackage(
                    workFlowContainer.getBaseObjectOid(), workFlowContainer.getBaseObjectOtype());
            List<FlowObject> flowObjectList = typlmFlowObjectPackageLinkService.batchUpdateLast(listByPackage);
            if (flowObjectList == null) {
                log.info(
                        "CheckCISIntergrateListener，获取到的流程对象为空，不处理，请检查数据！");
                return result;
            }

            for (FlowObject flowObject : flowObjectList) {
                BigInteger newBOMPartOid = flowObject.getRefObjectOid();
                String oType = flowObject.getRefObjectOtype();
                PartDetailsVO newBOMPartDetailsVO = typlmPartService.queryPartDetails(newBOMPartOid, oType);
                if (newBOMPartDetailsVO == null) {
                    continue;
                }
                result.add(newBOMPartDetailsVO);
                log.info("CheckCISIntergrateListener，当前正在处理的PartDetailsVO对象{}",
                         newBOMPartDetailsVO.toString());
            }
        }
        return result;
    }

    public void checkWorkflowPart(List<PartDetailsVO> partDetailsVOList) {
        CisAdDTOService cisAdDTOService = (CisAdDTOService) SpringUtil.getBean(
                CisAdDTOService.class);
        TyplmClassificationService typlmClassificationService = (TyplmClassificationService) SpringUtil.getBean(
                TyplmClassificationService.class);
        TyplmFileHandleService typlmFileHandleService = (TyplmFileHandleService) SpringUtil.getBean(
                TyplmFileHandleService.class);
        TyplmPdmPartService typlmPdmPartService = (TyplmPdmPartService) SpringUtil.getBean(
                TyplmPdmPartService.class);
        TyplmFileService typlmFileService = (TyplmFileService) SpringUtil.getBean(
                TyplmFileService.class);

        // cis.ad.classificationLevel 取第几个分类层级进行判断
        // cis.ad.classificationOfElectronicComponents 属于电子物料的分类名称，多个的用逗号隔开
        String classificationLevel = SpringUtil.getProperty("cis.ad.classificationLevel");
        String classificationOfElectronicComponents = SpringUtil.getProperty(
                "cis.ad.classificationOfElectronicComponents");
        if (!org.springframework.util.StringUtils.hasText(classificationOfElectronicComponents)) {
            throw new IllegalArgumentException("需要配置(cis.ad.classificationOfElectronicComponents)");
        }
        String[] classificationOfElectronicComponentsList = classificationOfElectronicComponents.split(";");
        String pcbDocLibTypeName = SpringUtil.getProperty("cis.ad.pcbDocLibTypeName");
        String schDocLibTypeName = SpringUtil.getProperty("cis.ad.schDocLibTypeName");

        List<CisAdDTO> cisAdDTOList = cisAdDTOService.queryCisAd(new CisAdDTO());
        //检查每个零部件的数据
        for (PartDetailsVO partDetailsVO : partDetailsVOList) {
            try {
                // 从properties文件获取需要集成cis库的电子元件分类
                Map<String, String> intactPathByClassificationOid = typlmClassificationService.getIntactPathByClassificationOid(
                        partDetailsVO.getClassId());
                String[] intactPath = intactPathByClassificationOid.get("intactPath").substring(1).split("/");
                String classificationName = intactPath[Integer.parseInt(classificationLevel)];
                log.info(intactPathByClassificationOid.toString());

                //  如果是需要集成CIS库的电子元器件分类的
                if (Arrays.asList(classificationOfElectronicComponentsList).contains(classificationName)) {

                    CisAdDTO cisAdDTO = new CisAdDTO();
                    cisAdDTO.setCodeNumber(partDetailsVO.getNumber());
                    cisAdDTO.setName(partDetailsVO.getName());
                    // TODO 改成properties可配置文件
                    cisAdDTO.setSpecificationModel(partDetailsVO.getIbaAttributeMap().get("规格型号").get(0));
                    cisAdDTO.setLibraryRef(partDetailsVO.getIbaAttributeMap().get("规格型号").get(0));
                    cisAdDTO.setFootprintRef(partDetailsVO.getIbaAttributeMap().get("封装").get(0));

                    //首先检查参考文档
                    List<DocDetails> list = typlmPdmPartService.getPartLinkReferenceDoc(partDetailsVO.getOid());
                    boolean hasRefSchDocObject = false;
                    boolean hasRefPcbDocObject = false;

                    for (DocDetails docDetail : list) {
                        if (docDetail.getTypeName().equals(pcbDocLibTypeName)) {
                            IdentifierEntity docEntity = new IdentifierEntity();
                            docEntity.setOid(BigInteger.valueOf(Long.parseLong((docDetail.getOid()))));
                            docEntity.setOtype(docDetail.getOtype());
                            List<FileDataVO> fileDataVOs = typlmFileHandleService.getFileListByEntity(docEntity);
                            String pcbFileName = fileDataVOs.get(0).getFileName(); // 获取原始文件名
                            cisAdDTO.setFootprintPath(pcbFileName);
                            hasRefPcbDocObject = true;
                        }
                        if (docDetail.getTypeName().equals(schDocLibTypeName)) {
                            IdentifierEntity docEntity = new IdentifierEntity();
                            docEntity.setOid(BigInteger.valueOf(Long.parseLong((docDetail.getOid()))));
                            docEntity.setOtype(docDetail.getOtype());
                            List<FileDataVO> fileDataVOs = typlmFileHandleService.getFileListByEntity(docEntity);
                            String schFileName = fileDataVOs.get(0).getFileName(); // 获取原始文件名
                            cisAdDTO.setLibraryPath(schFileName);
                            hasRefSchDocObject = true;
                        }
                    }
                    //如果已经从关联的文档中获取到文件，则跳过该元器件
                    if (hasRefPcbDocObject && hasRefSchDocObject) {
                        cisAdDTOList.add(cisAdDTO);
                        continue;
                    }
                    //如果找不到关联的文档，则尝试从附件中获取文件
                    IdentifierEntity entity = new IdentifierEntity();
                    entity.setOid(BigInteger.valueOf(Long.parseLong((partDetailsVO.getOid()))));
                    entity.setOtype(partDetailsVO.getOtype());
                    List<FileDataVO> fileListByEntity = typlmFileHandleService.getFileListByEntity(entity);
                    for (FileDataVO fileDataVO : fileListByEntity) {
                        if (fileDataVO.getFileName().toLowerCase().endsWith(".pcblib")) {
                            cisAdDTO.setFootprintPath(fileDataVO.getFileName());
                        }
                        if (fileDataVO.getFileName().toLowerCase().endsWith(".schlib")) {
                            cisAdDTO.setLibraryPath(fileDataVO.getFileName());
                        }
                    }
                    cisAdDTOList.add(cisAdDTO);
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error("CheckCISIntergrateListener，生成文档异常：", e);
            }
        }
        for (CisAdDTO cisAdDTO : cisAdDTOList) {
            // TODO 检查未来集成CIS库的记录是否正确
        }
    }

    /**
     * 将输入流保存到指定路径，若文件已存在则先删除，最后返回文件全路径
     *
     * @param inputStream 输入流
     * @param targetFolderPath 目标文件夹路径
     * @param originalFilename 原始文件名
     * @return 保存后的文件全路径
     */
    private String saveInputStreamToFile(InputStream inputStream, String targetFolderPath, String originalFilename) {
        try {
            // 创建目标路径目录（如果不存在）
            Path targetPath = Paths.get(targetFolderPath);
            if (!Files.exists(targetPath)) {
                Files.createDirectories(targetPath);
            }

            // 拼接完整的目标文件路径
            Path destinationFile = targetPath.resolve(originalFilename);

            // 如果文件已存在，则删除
            if (Files.exists(destinationFile)) {
                Files.delete(destinationFile);
                log.info("已删除旧文件: {}", destinationFile.toString());
            }

            // 写入文件
            try (FileOutputStream outputStream = new FileOutputStream(destinationFile.toFile())) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
            }

            log.info("文件已保存至: {}", destinationFile.toString());

            // 返回文件全路径
            return destinationFile.toString();

        } catch (IOException e) {
            log.error("保存文件时发生异常，目标路径：{}, 文件名：{}", targetFolderPath, originalFilename, e);
            return null; // 出现异常返回 null
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                log.warn("关闭输入流时发生异常", e);
            }
        }
    }


}
